﻿@* Generator: Template TypeVisibility: Internal GeneratePrettyNames: true *@
@using System
@using System.Collections.Generic
@using Hangfire
@using Hangfire.Dashboard
@using Hangfire.Dashboard.Pages
@using Hangfire.Dashboard.Resources
@using Hangfire.States
@using Hangfire.Storage
@inherits RazorPage
@{
    Layout = new LayoutPage(Strings.RecurringJobsPage_Title);
	List<RecurringJobDto> recurringJobs;
    
    int from, perPage;

    int.TryParse(Query("from"), out from);
    int.TryParse(Query("count"), out perPage);

    Pager pager = null;

	using (var connection = Storage.GetReadOnlyConnection())
	{
	    var storageConnection = connection as JobStorageConnection;
	    if (storageConnection != null)
	    {
	        pager = new Pager(from, perPage, DashboardOptions.DefaultRecordsPerPage, storageConnection.GetRecurringJobCount());
	        recurringJobs = storageConnection.GetRecurringJobs(pager.FromRecord, pager.FromRecord + pager.RecordsPerPage - 1);
	    }
	    else
	    {
            recurringJobs = connection.GetRecurringJobs();
	    }
	}
}

<div class="row">
    <div class="col-md-12">
        <h1 id="page-title" class="page-header">@Strings.RecurringJobsPage_Title</h1>
        @if (recurringJobs.Count == 0)
        {
            <div class="alert alert-info">
                @Strings.RecurringJobsPage_NoJobs
            </div>
        }
        else
        {
            <div class="js-jobs-list">
                <div class="btn-toolbar btn-toolbar-top">
                    @if (!IsReadOnly)
                    {
                        <button class="js-jobs-list-command btn btn-sm btn-primary"
                                data-url="@Url.To("/recurring/trigger")"
                                data-loading-text="@Strings.RecurringJobsPage_Triggering"
                                disabled="disabled">
                            <span class="glyphicon glyphicon-play-circle"></span>
                            @Strings.RecurringJobsPage_TriggerNow
                        </button>
                    }
                    @if (!IsReadOnly)
                    {
                        <button class="js-jobs-list-command btn btn-sm btn-default"
                                data-url="@Url.To("/recurring/remove")"
                                data-loading-text="@Strings.Common_Deleting"
                                data-confirm="@Strings.Common_DeleteConfirm"
                                disabled="disabled">
                            <span class="glyphicon glyphicon-remove"></span>
                            @Strings.Common_Delete
                        </button>
                    }
                    @if (pager != null)
                    {
                        @: @Html.PerPageSelector(pager)
                    }
                </div>

                <div class="table-responsive">
                    <table class="table" aria-describedby="page-title">
                        <thead>
                            <tr>
                                @if (!IsReadOnly)
                                {
                                    <th class="min-width">
                                        <input type="checkbox" class="js-jobs-list-select-all"/>
                                    </th>
                                }
                                <th>@Strings.Common_Id</th>
                                <th class="min-width">@Strings.RecurringJobsPage_Table_Cron</th>
                                <th>@Strings.RecurringJobsPage_Table_TimeZone</th>
                                <th>@Strings.Common_Job</th>
                                <th class="align-right min-width">@Strings.RecurringJobsPage_Table_NextExecution</th>
                                <th class="align-right min-width">@Strings.RecurringJobsPage_Table_LastExecution</th>
                                <th class="align-right min-width">@Strings.Common_Created</th>
                            </tr>
                        </thead>
                        <tbody>
                            @foreach (var job in recurringJobs)
                            {
                                <tr class="js-jobs-list-row hover">
                                    @if (!IsReadOnly)
                                    {
                                        <td rowspan="@(job.Error != null ? "2" : "1")">
                                            <input type="checkbox" class="js-jobs-list-checkbox" name="jobs[]" value="@job.Id"/>
                                        </td>
                                    }
                                    <td class="word-break">@job.Id</td>
                                    <td class="min-width min-width-125p ">
                                        @* ReSharper disable once EmptyGeneralCatchClause *@
                                        @{
                                            string cronDescription = null;
                                            bool cronError = false;

                                            if (!String.IsNullOrEmpty(job.Cron))
                                            {
                                                try
                                                {
                                                    RecurringJobEntity.ParseCronExpression(job.Cron);
                                                }
                                                catch (Exception ex) when (ex.IsCatchableExceptionType())
                                                {
                                                    cronDescription = ex.Message;
                                                    cronError = true;
                                                }

                                                if (cronDescription == null)
                                                {
#if FEATURE_CRONDESCRIPTOR
                                                    try
                                                    {
                                                        cronDescription = CronExpressionDescriptor.ExpressionDescriptor.GetDescription(job.Cron);
                                                    }
                                                    catch (FormatException)
                                                    {
                                                    }
#endif
                                                }
                                            }
                                        }

                                        @if (cronDescription != null)
                                        {
                                        <code title="@cronDescription" class="cron-badge">
                                            @if (cronError)
                                            {
                                                <span class="glyphicon glyphicon-exclamation-sign"></span>
                                            }
                                            @job.Cron
                                        </code>
                                        }
                                        else
                                        {
                                            <code class="cron-badge">@job.Cron</code>
                                        }
                                    </td>
                                    <td>
                                        @if (!String.IsNullOrWhiteSpace(job.TimeZoneId))
                                        {
                                            string displayName;
                                            Exception exception = null;

                                            try
                                            {
                                                var resolver = DashboardOptions.TimeZoneResolver ?? new DefaultTimeZoneResolver();
                                                displayName = resolver.GetTimeZoneById(job.TimeZoneId).DisplayName;
                                            }
                                            catch (Exception ex) when (ex.IsCatchableExceptionType())
                                            {
                                                displayName = null;
                                                exception = ex;
                                            }

                                            <span title="@displayName" data-container="body">@job.TimeZoneId
                                                @if (exception != null)
                                                {
                                                    <span class="glyphicon glyphicon-exclamation-sign" title="@exception.Message"></span>
                                                }
                                            </span>
                                        }
                                        else
                                        {
                                            @: UTC
                                        }
                                    </td>
                                    <td class="word-break width-30">
                                        @if (job.Job != null)
                                        {
                                            @: @Html.JobName(job.Job)
                                        }
                                        else if (job.LoadException != null && job.LoadException.InnerException != null)
                                        {
                                            <em>@job.LoadException.InnerException.Message</em>
                                        }
                                        else if (job.LoadException != null)
                                        {
                                            <em>@job.LoadException.Message</em>
                                        }
                                        else
                                        {
                                            <em>@Strings.Common_NotAvailable</em>
                                        }
                                    </td>
                                    <td class="align-right min-width">
                                        @if (!job.NextExecution.HasValue)
                                        {
                                            if (job.Error != null)
                                            {
                                                <span class="label label-danger text-uppercase">@Strings.Common_Error</span>
                                            }
                                            else
                                            {
                                                <span class="label label-default text-uppercase" title="@Strings.RecurringJobsPage_RecurringJobDisabled_Tooltip">@Strings.Common_Disabled</span>
                                            }

                                        }
                                        else if (job.RetryAttempt > 0)
                                        {
                                            <span class="label label-warning">@Html.RelativeTime(job.NextExecution.Value)</span>
                                        }
                                        else
                                        {
                                            @Html.RelativeTime(job.NextExecution.Value)
                                        }
                                    </td>
                                    <td class="align-right min-width">
                                        @if (job.LastExecution != null)
                                        {
                                            if (!String.IsNullOrEmpty(job.LastJobId))
                                            {
                                                <a href="@Url.JobDetails(job.LastJobId)" class="text-decoration-none">
                                                    @{
                                                        var cssSuffix = JobHistoryRenderer.GetStateCssSuffix(job.LastJobState ?? EnqueuedState.StateName);
                                                    }
                                                    @if (cssSuffix != null)
                                                    {
                                                        <span class="label label-default label-hover label-state-@cssSuffix">
                                                            @Html.RelativeTime(job.LastExecution.Value)
                                                        </span>
                                                    }
                                                    else
                                                    {
                                                        <span class="label label-default label-hover" style="@($"background-color: {JobHistoryRenderer.GetForegroundStateColor(job.LastJobState ?? EnqueuedState.StateName)};")">
                                                            @Html.RelativeTime(job.LastExecution.Value)
                                                        </span>
                                                    }
                                                </a>
                                            }
                                            else
                                            {
                                                <span class="label label-default label-state-inactive" title="@Strings.RecurringJobsPage_Canceled">
                                                    @Html.RelativeTime(job.LastExecution.Value)
                                                </span>
                                            }
                                        }
                                        else
                                        {
                                            <em>@Strings.Common_NotAvailable</em>
                                        }
                                    </td>
                                    <td class="align-right min-width">
                                        @if (job.CreatedAt != null)
                                        {
                                            @Html.RelativeTime(job.CreatedAt.Value)
                                        }
                                        else
                                        {
                                            <em>N/A</em>
                                        }
                                    </td>
                                    @if (job.Error != null)
                                    {
                                        <tr>
                                            <td colspan="@(IsReadOnly ? "6" : "7")" class="failed-job-details">
                                                <pre class="stack-trace"><code>@Html.StackTrace(job.Error)</code></pre>
                                            </td>
                                        </tr>
                                    }
                                </tr>
                             }
                        </tbody>
                    </table>
                </div>

                @if (pager != null)
                {
                    @: @Html.Paginator(pager)
                }
            </div>
        }
    </div>
</div>    